package view.transitions;

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.logging.Level;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

import model.Preference;
import model.Settings;
import model.contents.Content;
import util.EmailSending;
import util.ExceptionTracker;
import util.LoggingUtils;

public class TransitionBox extends JPanel {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public static final int	NO_TRANSITION	= -1;
	private Animator		animator;
	private int				width;
	private int				height;
	private String			transitionType;

	public TransitionBox(Content from, Content to, int width, int height, int transition, String transitionType) {
		this.width = width;
		this.height = height;
		this.transitionType = transitionType;
		this.setPreferredSize(new Dimension(width, height));
		this.setOpaque(false);
		this.setLayout(new BorderLayout());
		this.setIgnoreRepaint(true);
		this.setDoubleBuffered(true);
		this.createAnimator(from, to, transition,transitionType);
	}

	private void createAnimator(Content from, Content to, int transition,String transitionType) {
		try {
			File originalImageFile = new File(from.getLocalPath());
			File overlayImageFile = new File(to.getLocalPath()); 
			if(!originalImageFile.exists() || !overlayImageFile.exists()) {
				return;
			}
			BufferedImage originalImage = ImageIO.read(originalImageFile);

			BufferedImage overlayImage = ImageIO.read(overlayImageFile);
			BufferedImage original = null, overlay = null;
			if (originalImage != null) {
				original = new BufferedImage(this.width, this.height, BufferedImage.TYPE_INT_ARGB);
				Graphics g2 = original.getGraphics();
				g2.drawImage(originalImage, 0, 0, this.width, this.height, null, null);
				g2.dispose();
			}
			if (overlayImage != null) {
				overlay = new BufferedImage(this.width, this.height, BufferedImage.TYPE_INT_ARGB);
				Graphics g2 = overlay.getGraphics();
				g2.drawImage(overlayImage, 0, 0, this.width, this.height, null, null);
				g2.dispose();
			}
			if (original != null && overlay != null) {
				this.animator = Animator.createAnimator(original, overlay, transition,transitionType);
				// this.animator = new RandomBarTransition(original, overlay);
			}
			originalImage.flush();
			overlayImage.flush();
			originalImage = null;
			overlayImage = null;
			System.gc();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			from.delete();
			to.delete();
			from.setHasUpdate(true);
			to.setHasUpdate(true);
			//e.printStackTrace();

			String classMethod = "view.transitions.TransitionBox in .createAnimator()";
			LoggingUtils.logStart(classMethod);
			LoggingUtils.log(Level.SEVERE,e.getMessage() + classMethod,e);

			final String exceptionmessage = EmailSending.FormatException(e);
			final String imageLoc = from.getLocalPath();

			if(!ExceptionTracker.isExceptionNotifiedByKey(imageLoc))
			{
				ExceptionTracker.setExceptionInTracker(imageLoc,e.getMessage());

				Thread emailingThread = new Thread(new Runnable() {
					@Override
					public void run() {

						String EmailBody = EmailSending.ProcessEmailBody(imageLoc+" has formating problem", 
								"general error:Notification, Image not playing", exceptionmessage);

						util.EmailSending.getInstance().send(Settings.TO_USER, "Image error:Notification" +
								"BoxID="+Preference.getInstance().getBoxID(), EmailBody);
					}
				});
				emailingThread.setName("Emailing");
				emailingThread.start();
			}

			/* Sending to production request to webtool 
			Thread sendConvertImage = new Thread(new Runnable() {
				@Override
				public void run() {

					HttpRequestFacade.PostToConvertImage(imageLoc, exceptionmessage);
				}
			});

			sendConvertImage.setName("Convert image");
			sendConvertImage.start();
			 */
			return;
		}
		catch(Error e)
		{
			// TODO Auto-generated catch block
			from.delete();
			to.delete();
			from.setHasUpdate(true);
			to.setHasUpdate(true);
			//e.printStackTrace();

			String classMethod = "view.transitions.TransitionBox in .createAnimator()";
			LoggingUtils.logStart(classMethod);
			LoggingUtils.log(Level.SEVERE,e.getMessage() + classMethod,e);

			final String exceptionmessage = EmailSending.FormatException(e);
			final String imageLoc = from.getLocalPath();

			if(!ExceptionTracker.isExceptionNotifiedByKey(imageLoc))
			{
				ExceptionTracker.setExceptionInTracker(imageLoc,e.getMessage());

				Thread emailingThread = new Thread(new Runnable() {
					@Override
					public void run() {

						String EmailBody = EmailSending.ProcessEmailBody(imageLoc+" has formating problem", 
								"general error:Notification, Image not playing", exceptionmessage);

						util.EmailSending.getInstance().send(Settings.TO_USER, "Image error:Notification" +
								"BoxID="+Preference.getInstance().getBoxID(), EmailBody);
					}
				});
				emailingThread.setName("Emailing");
				emailingThread.start();
			}

			return;
		}
		finally {
		}
	}

	@Override
	public void paintComponent(Graphics g) {
		if (this.animator == null) {
			return;
		}

		Graphics2D g2d = (Graphics2D) g;

		AlphaComposite originalComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
				this.animator.originalOpacity);
		g2d.setComposite(originalComposite);

		g2d.drawImage(this.animator.original, this.animator.originalPosition.x, this.animator.originalPosition.y, null,
				this);

		AlphaComposite overlayComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
				this.animator.overlayOpacity);
		g2d.setComposite(overlayComposite);
		g2d.drawImage(this.animator.overlay, this.animator.overlayPosition.x, this.animator.overlayPosition.y, null,
				this);
	}

	public String getTransitionType() {
		return transitionType;
	}

	public void setTransitionType(String transitionType) {
		this.transitionType = transitionType;
	}

	public void animate() {
		if (this.animator == null) {
			return;
		}
		while (this.animator.isAnimatable()) {
			this.animator.animate();
			this.revalidate();
			this.repaint();
			
			int delay = 5;
			try
			{
				if(this.getTransitionType().equals("Normal")){ delay = 3; }
				else if(this.getTransitionType().equals("Fast")){ delay = 1; }
				else if(this.getTransitionType().equals("Slow")){ delay = 8; }
				else	{ delay = 3; }
			}catch(Exception e)
			{
				delay = 3;
			}
			
			
			try {
				Thread.sleep(delay);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block

				String classMethod = "view.transitions.TransitionBox in .animate()";
				LoggingUtils.logStart(classMethod);
				LoggingUtils.log(Level.SEVERE,e.getMessage() + classMethod,e);

				e.printStackTrace();
			}
		}
	}
}
